package com.umpay.sp.saas.action.batchNet;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

import org.apache.struts2.ServletActionContext;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.opensymphony.xwork2.Preparable;
import com.umpay.operation.common.ReqMessage;
import com.umpay.operation.common.ResMessage;
import com.umpay.operation.model.saas.StoreBatchDetail;
import com.umpay.operation.service.saas.TStoreBatchDetailServiceRemote;
import com.umpay.operation.service.saas.TStoreBatchServiceRemote;
import com.umpay.operation.service.saas.UserServiceRemote;
import com.umpay.operation.xml.XmlData;
import com.umpay.sp.common.consdata.ConstantDefined;
import com.umpay.sp.saas.util.DubboInvokerUtil;
import com.umpay.sp.saas.util.HttpRequest;
import com.umpay.sp.util.ConstEC;
import com.umpay.sp.util.StringUtil;
import com.umpay.sp.web.action.sys.BaseAction;
import com.umpay.sp.web.util.FileUtil;
import com.umpay.sp.web.util.MatrixUtil;
import com.umpay.sp.web.util.PageView;
import com.umpay.sp.web.util.PropertyUtil;
import com.umpay.sp.web.util.ZipUtil;

public class StoreBatchAction extends BaseAction implements Preparable {

	/**
	 * long:serialVersionUID
	 */
	private static final long serialVersionUID = 1L;

	//证书路径
	public static final String MERCERURL = PropertyUtil.getStrValue("spEnterpriseWeb_config.properties", "saas.server.certDirectory");
	//打包路径
	public static final String ZIPDIRECTORY = PropertyUtil.getStrValue("spEnterpriseWeb_config.properties", "saas.server.zipDirectory");
	//获取公众号收款人邀请二维码Url列表
	public static final String PAYEETICKETURLLIST = PropertyUtil.getStrValue("spEnterpriseWeb_config.properties", "saas.server.payeeTicketUrlList");

	//登录用户编号
	private String userId;
	//批次号
	private String batchNo;
	private String detailBatchNo;
	
	//开始时间
	private String startDate;
	//结束时间
	private String endDate;
	//操作状态
	private String optStatus;
	// 分页
	private PageView pageView;
	HttpServletRequest request = ServletActionContext.getRequest();
	HttpServletResponse response = ServletActionContext.getResponse();
	
	/**
	 * 跳转到批次信息显示页面
	 * 
	 * @return
	 */
	public String storeBatchListView(){
		return "storeBatchCtrl";
	}
	
	/**
	 * 1.批量申请状态查询
	 * 
	 * @return
	 */
	public String getCntBatchList(){
		log.info("【批量申请状态查询】开始");
		try{
			String paramPage = request.getParameter("currentPage") == null ? "1" : request.getParameter("currentPage");
			pageView = new PageView(Integer.parseInt(paramPage));
			//登录代理商编号
			String agentId= StringUtil.trim(this.getSession().get(XmlData.AGENTID));
			
			ReqMessage reqMessage = new ReqMessage();
			//代理商编号
			reqMessage.put(XmlData.AGENTID, agentId);
			//批次号
			reqMessage.put(XmlData.BATCHNO, batchNo);
			//开始日期
			reqMessage.put(XmlData.START_DATE, startDate);
			//结束日期
			reqMessage.put(XmlData.END_DATE, endDate);
			//操作状态 
			reqMessage.put(XmlData.STATE, optStatus);
			//当前页
			reqMessage.put(XmlData.CURRENT_PAGE, pageView.getCurrentpage());
			//每页条数
			reqMessage.put(XmlData.PAGE_SIZE, pageView.getPagecode());
			
			log.info("【统计批次详情信息】入参：" + reqMessage);
			TStoreBatchServiceRemote tStoreBatchServiceRemote = 
					DubboInvokerUtil.getInvoker(TStoreBatchServiceRemote.class);
			ResMessage resMessage = tStoreBatchServiceRemote.countStoreBatchList(reqMessage);
			log.info("【统计批次详情信息】出参：" + resMessage);
			if(!resMessage.getRetCode().equals(ConstantDefined.SUCCESS)){
				log.info("统计批次列表查询失败");
				return ERROR;
			}
			List<Map<String, Object>> resultList = 
					(List<Map<String, Object>>)resMessage.getValue(XmlData.STORE_BATCH_LIST);
			
			if(resultList != null && resultList.size() > 0){
				pageView.setRecords(resultList);
				//总条数
				pageView.setTotalrecord(Long.valueOf(resMessage.getValue(XmlData.STORE_BATCH_COUNT).toString()));
			}
			log.info("统计批次列表查询成功，返回信息=" + pageView);
		
		}catch(Exception e){
			e.printStackTrace();
			log.error("统计批次列表查询失败", e);
			return ERROR;
		}
		
		return SUCCESS;
	}
	
	/**
	 * 2.批量下载邀请码
	 * 
	 * @return
	 */
	public String batchUploadInvitationCode(){
		log.info("【批量下载邀请码】开始");
		try{
			ReqMessage reqMessage = new ReqMessage();
			//批次号
			reqMessage.put(XmlData.BATCHNO, detailBatchNo);
			log.info("【批次明细列表查询】入参：" + reqMessage);
			TStoreBatchDetailServiceRemote storeBatchDetailServiceRemote = 
					DubboInvokerUtil.getInvoker(TStoreBatchDetailServiceRemote.class);
			ResMessage resMessage = storeBatchDetailServiceRemote.queryBatchDetailList(reqMessage);
			log.info("【批次明细列表查询】出参：" + resMessage);
			if(!resMessage.getRetCode().equals(ConstantDefined.SUCCESS)){
				log.info("批次明细列表查询失败");
				return ERROR;
			}
			
			//批次明细列表
			List<StoreBatchDetail> storeBatchDetailList = 
					(List<StoreBatchDetail>)resMessage.getValue(XmlData.STORE_BATCH_DETAIL_LIST);
			if(storeBatchDetailList == null || storeBatchDetailList.size() == 0){
				log.info("无邀请码可下载");
				errorMessage = "无邀请码可下载";
				return "errorDown";
			}
			
			//邀请码参数Map
			Map<String, Object> codeMap = new HashMap<String, Object>();
			for(StoreBatchDetail detail : storeBatchDetailList){
				log.info("批次详情：" + detail.toString());
				String merId = detail.getMerId();
				String storeId = detail.getStoreId();
				if(StringUtil.isEmpty(merId) || StringUtil.isEmpty(storeId)){
					continue;
				}
				//查询用户列表
				reqMessage = new ReqMessage();
				reqMessage.put(XmlData.MERFLAG, merId);//主商户
				reqMessage.put(XmlData.STATE,"0");//状态
				reqMessage.put(XmlData.RANK,"0");//角色
				reqMessage.put(XmlData.CURRENT_PAGE, String.valueOf(1));
				reqMessage.put(XmlData.PAGE_SIZE, String.valueOf(1));
				log.info("【查询用户列表】入参：" + reqMessage);
				UserServiceRemote userServiceRemote = DubboInvokerUtil.getInvoker(UserServiceRemote.class);
				resMessage = userServiceRemote.queryList(reqMessage);
				log.info("【查询用户列表】出参：" + resMessage);
				if(!resMessage.getRetCode().equals(ConstantDefined.SUCCESS)){
					log.info("用户列表查询失败");
					return ERROR;
				}
				//用户列表
				List<Map<String, Object>> userList = 
						(List<Map<String, Object>>)resMessage.getValue(XmlData.RESULT_LIST);
				//有用户编号，则表示已经审核通过
				if(userList != null && userList.size() > 0){
					codeMap.put(storeId, userList.get(0).get(XmlData.USERID));
				}
			}
			if(codeMap.size() == 0){
				log.info("无邀请码可下载");
				errorMessage = "无邀请码可下载";
				return "errorDown";
			}
			
			//获取邀请码列表
			String codeMapStr = JSONObject.fromObject(codeMap).toString();
			log.info("【获取邀请码列表】访问路径" + PAYEETICKETURLLIST + "; 入参:" + codeMapStr);
			String resultStr = HttpRequest.sendPost(PAYEETICKETURLLIST, codeMapStr);
			Map<String, String> codeUrlMap = new Gson().fromJson(resultStr, new TypeToken<Map<String, String>>(){}.getType());
			log.info("【获取邀请码列表】出参：" + codeUrlMap);
			if(codeUrlMap == null || codeUrlMap.size() == 0){
				log.info("无邀请码可下载");
				errorMessage = "无邀请码可下载";
				return "errorDown";
			}
			
			//生成二维码图片路径
			List<String> filePathList = new ArrayList<String>();
			List<File> fileList = new ArrayList<File>();
			for(StoreBatchDetail detail : storeBatchDetailList){ 
				//店铺编号
				String storeId = detail.getStoreId();
				//图片路径+图片名称
				StringBuilder fileUrlSb = new StringBuilder();
				//图片路径
				fileUrlSb.append(ZIPDIRECTORY + File.separator);
				//收款人姓名
				fileUrlSb.append(detail.getPayeeName());
				fileUrlSb.append("_");
				//店铺名称
				fileUrlSb.append(detail.getStoreShortName());
				//店铺编号
				fileUrlSb.append("(");
				fileUrlSb.append(storeId);
				fileUrlSb.append(")");
				//图片格式
				fileUrlSb.append(".jpg");
				//文件
				log.info("文件路径：" + fileUrlSb.toString() + " 编码格式：" + System.getProperty("sun.jnu.encoding"));
				System.setProperty("sun.jnu.encoding", "utf-8");
				File file = new File(fileUrlSb.toString());
				log.info("文件名称file：" + file.getName());
				//二维码信息
				String content = codeUrlMap.get(storeId);
				log.info("店铺编号：" + storeId + "; 二维码信息：" + content);
				if(StringUtil.isNotEmpty(content)){
					//生成二维码图片 
					MatrixUtil.writeToFile(content, file);
					filePathList.add(fileUrlSb.toString());
					fileList.add(file);
				}
			}
			
			//压缩文件名：批次号_code.zip
			StringBuilder zipFileNameSb = new StringBuilder();
			zipFileNameSb.append(detailBatchNo);
			zipFileNameSb.append("_邀请码.zip");
			//打包文件
			File zipFile = new File(ZIPDIRECTORY, zipFileNameSb.toString());
			ZipUtil.zip(zipFile, filePathList);
			//下载打包文件
			FileUtil.downLoadZipFile(zipFile, request, response);
			fileList.add(zipFile);
			
			//删除文件
			deleteFiles(fileList);
			log.info("下载邀请码压缩文件成功！");
			return null;
			
		}catch(Exception e){
			e.printStackTrace();
			log.error("批量下载邀请码失败", e);
			return ERROR;
		}
	}
	
	/**
	 * 3.批量下载证书
	 * 
	 * @return
	 */
	public String batchUploadCerts(){
		log.info("【批量下载证书】开始");
		try{
			ReqMessage reqMessage = new ReqMessage();
			//批次号
			reqMessage.put(XmlData.BATCHNO, detailBatchNo);
			log.info("【批次明细列表查询】入参：" + reqMessage);
			TStoreBatchDetailServiceRemote tStoreBatchDetailServiceRemote = 
					DubboInvokerUtil.getInvoker(TStoreBatchDetailServiceRemote.class);
			ResMessage resMessage = tStoreBatchDetailServiceRemote.queryBatchDetailList(reqMessage);
			log.info("【批次明细列表查询】出参：" + resMessage);
			if(!resMessage.getRetCode().equals(ConstantDefined.SUCCESS)){
				log.info("批次明细列表查询失败");
				return ERROR;
			}
			
			//批次明细列表
			List<StoreBatchDetail> storeBatchDetailList = 
					(List<StoreBatchDetail>)resMessage.getValue(XmlData.STORE_BATCH_DETAIL_LIST);
			if(storeBatchDetailList == null || storeBatchDetailList.size() == 0){
				log.info("无证书可下载");
				errorMessage = "无证书可下载";
				return "errorDown";
			}
			
			List<File> fileList = new ArrayList<File>();
			List<String> filePathList = new ArrayList<String>();
			for(StoreBatchDetail detail : storeBatchDetailList){
				String storeId = detail.getStoreId();
				if(StringUtil.isNotEmpty(storeId)){
					//压缩文件名：收款人姓名_店铺名称（商户号）证书
					StringBuilder zipFileNameSb = new StringBuilder();
					//收款人姓名
					zipFileNameSb.append(detail.getPayeeName());
					zipFileNameSb.append("_");
					//店铺名称
					zipFileNameSb.append(detail.getStoreShortName());
					//店铺编号
					zipFileNameSb.append("(");
					zipFileNameSb.append(storeId);
					zipFileNameSb.append(")证书.zip");
					//打包文件
					File zipFile = zipFile(zipFileNameSb.toString(), MERCERURL + storeId + "/");
					if(zipFile.exists()){
						fileList.add(zipFile);
						filePathList.add(ZIPDIRECTORY + zipFileNameSb.toString());
					}
				}
			}
			
			if(filePathList.size() == 0){
				log.info("无证书可下载");
				errorMessage = "无证书可下载";
				return "errorDown";
			}
			//压缩文件名：批次号+证书.zip
			StringBuilder zipFileNameSb = new StringBuilder();
			zipFileNameSb.append(detailBatchNo);
			zipFileNameSb.append("证书.zip");
			//打包文件
			File zipFile = new File(ZIPDIRECTORY, zipFileNameSb.toString());
			ZipUtil.zip(zipFile, filePathList);
			//打包下载文件
			FileUtil.downLoadZipFile(zipFile, request, response);
			fileList.add(zipFile);
			//删除文件
			deleteFiles(fileList);
		    log.info("下载证书压缩文件成功！");
			return null;
		}catch(Exception e){
			e.printStackTrace();
			log.error("批量下载证书失败", e);
			return ERROR;
		}
	}
	
	/**
	 * 打包文件
	 * 
	 * @param zipFileName 压缩文件名
	 * @param downLoadUrl 压缩文件路径
	 * @return
	 * @throws Exception
	 */
	private File zipFile(String zipFileName, String downLoadUrl) throws Exception {
		File zipFile = new File(ZIPDIRECTORY, zipFileName);
		log.info("打包文件路：" + ZIPDIRECTORY + zipFileName);
		//文件路径集合
		String[] names = new File(downLoadUrl).list();
		if(names != null){
			List<String> fileNameList = new ArrayList<String>();
			for (String name : names) {
				fileNameList.add(downLoadUrl + name);
			}
			//打包文件
			ZipUtil.zip(zipFile, fileNameList);
			log.info("打包文件成功！");
		}
		
		return zipFile;
	}
	
	/**
	 * 删除文件
	 * 
	 * @param fileList
	 */
	public void deleteFiles(List<File> fileList){
		if(fileList != null && fileList.size() > 0){
			for(File file : fileList){
				file.delete();
			}
		}
	}
	
	/**
	 * 操作状态
	 * 
	 * @return
	 */
	public Map<String, String> getBatchState() {
		Map<String, String> map = new HashMap<String, String>();
		map.put(ConstEC.BATCH_STATE_0, "已完成");
		map.put(ConstEC.BATCH_STATE_1, "处理中");
		map.put(ConstEC.BATCH_STATE_2, "批次待处理");
		return map;
	}
	
	public void prepare() throws Exception {

	}

	public String getUserId() {
		return userId;
	}

	public void setUserId(String userId) {
		this.userId = userId;
	}

	public String getBatchNo() {
		return batchNo;
	}

	public void setBatchNo(String batchNo) {
		this.batchNo = batchNo;
	}

	public String getDetailBatchNo() {
		return detailBatchNo;
	}

	public void setDetailBatchNo(String detailBatchNo) {
		this.detailBatchNo = detailBatchNo;
	}

	public String getStartDate() {
		return startDate;
	}

	public void setStartDate(String startDate) {
		this.startDate = startDate;
	}

	public String getEndDate() {
		return endDate;
	}

	public void setEndDate(String endDate) {
		this.endDate = endDate;
	}

	public String getOptStatus() {
		return optStatus;
	}

	public void setOptStatus(String optStatus) {
		this.optStatus = optStatus;
	}

	public PageView getPageView() {
		return pageView;
	}
	public void setPageView(PageView pageView) {
		this.pageView = pageView;
	}
}